package gundamwar;

import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

/**
 * @author kcluk
 * 
 */
@SuppressWarnings("serial")
public class KeyboardPanel extends JPanel {
	Gundam gundam = new Gundam();
	Boss boss = new Boss();
	List<Gok> gokList = new ArrayList<Gok>();
	List<Bombs> bombsList = new ArrayList<Bombs>();
	List<Missiles> missilesList = new ArrayList<Missiles>();
	List<Laser> laserList = new ArrayList<Laser>();

	Calendar beginTime = Calendar.getInstance();

	// Timer
	Timer bossTimer = new Timer();
	Timer gokTimer2 = new Timer();
	Timer gokTimer = new Timer();
	Timer bombsTimer2 = new Timer();
	Timer bombsTimer = new Timer();
	Timer missilesTimer2 = new Timer();
	Timer missilesTimer = new Timer();
	Timer laserTimer = new Timer();
	Timer collisionTimer = new Timer();
	Timer remainingtimeTimer = new Timer();
	Timer endgameTimer = new Timer();

	int gokCounter = 0;
	int score=0;
	float remainingtime;
	float timeLeft = 0;

	public void endGame() {
		bossTimer.cancel();
		bossTimer.purge();
		gokTimer2.cancel();
		gokTimer2.purge();
		gokTimer.cancel();
		gokTimer.purge();
		bombsTimer2.cancel();
		bombsTimer2.purge();
		bombsTimer.cancel();
		bombsTimer.purge();
		missilesTimer.cancel();
		missilesTimer.purge();
		missilesTimer2.cancel();
		missilesTimer2.purge();
		laserTimer.cancel();
		laserTimer.purge();
		collisionTimer.cancel();
		collisionTimer.purge();
		remainingtimeTimer.cancel();
		remainingtimeTimer.purge();

	}

	public Gok createGok() {
		Gok gok = new Gok();
		return gok;
	}

	public Bombs createBombs() {
		Bombs bombs = new Bombs();
		bombs.starty = boss.y;
		return bombs;
	}

	public boolean randomGok() {
		Random random = new Random();
		return random.nextBoolean();

	}

	public Missiles createMissiles() {

		Missiles missiles = new Missiles();
		int r = (int) (Math.random() * 4);
		if (gokList.size() == 4) {
			missiles.x = gokList.get(r).x;
			missiles.y = gokList.get(r).y + 20;
			missiles.appear = true;



		}
		return missiles;

	}

	public void laserReleased() {
		int numberOfAppear = 0;
		for (int i = 0; i < laserList.size(); i++) {
			if (laserList.get(i).appear)
				numberOfAppear++;
		}


		if (numberOfAppear < 5) {
			Laser laser = new Laser();
			laser.x = gundam.x;
			laser.y = gundam.y;
			laserList.add(laser);
		}
	}

	public float Round(float Rval, int Rpl) {
		float p = (float) Math.pow(10, Rpl);
		Rval = Rval * p;
		float tmp = Math.round(Rval);
		return (float) tmp / p;
	}

	public KeyboardPanel() {
		addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {

				switch (e.getKeyCode()) {
				case KeyEvent.VK_DOWN:
					gundam.y += 10 * gundam.m;
					break;
				case KeyEvent.VK_UP:
					gundam.y -= 10 * gundam.m;
					break;
				case KeyEvent.VK_LEFT:
					gundam.x -= 10 * gundam.m;
					break;
				case KeyEvent.VK_RIGHT:
					gundam.x += 10 * gundam.m;
					break;
				case KeyEvent.VK_PAGE_UP:
					gundam.m *= 1.1;
					break;
				case KeyEvent.VK_PAGE_DOWN:
					gundam.m *= 0.9;
					break;
				case KeyEvent.VK_ENTER:
					// System.out.println("OK");
					laserReleased();
					break;
				default:
				}
				if (gundam.x > 1000 - 100)
					gundam.x = 1000 - 100;
				if (gundam.x < 0)
					gundam.x = 0;
				if (gundam.y > 600 - 100)
					gundam.y = 600 - 100;
				if (gundam.y < 0)
					gundam.y = 0;
				if (gundam.m > 6)
					gundam.m = 6;
				if (gundam.m < 0.5)
					gundam.m = 0.5;
				repaint();
			}

		});

	}

	BufferedImage[] backgroundImage = new BufferedImage[1];
	BufferedImage[] gundamImage = new BufferedImage[1];
	BufferedImage[] bossImage = new BufferedImage[1];
	BufferedImage[] gokImage = new BufferedImage[2];
	BufferedImage[] bombsImage = new BufferedImage[1];
	BufferedImage[] missileImage = new BufferedImage[1];
	BufferedImage[] laserImage = new BufferedImage[1];

	{

		// Load background image
		try {
			backgroundImage[0] = ImageIO
					.read(new File("images/background.jpg"));
			bossImage[0] = ImageIO.read(new File("images/boss.png"));
			gundamImage[0] = ImageIO.read(new File("images/gundam.png"));
			gokImage[0] = ImageIO.read(new File("images/gok.png"));
			gokImage[1] = ImageIO.read(new File("images/gok2.png"));
			bombsImage[0] = ImageIO.read(new File("images/bomb.png"));
			missileImage[0] = ImageIO
					.read(new File("images/missile_right.png"));
			laserImage[0] = ImageIO.read(new File("images/laser.png"));
		} catch (IOException e) {
			System.err.println("Cannot open the file");
		}

		bossTimer.schedule(new BossMove(), 0, 50);
		gokTimer2.schedule(new numberOfGok(), 0, 200);
		gokTimer.schedule(new GokMove(), 0, 50);
		bombsTimer2.schedule(new numberOfBombs(), 0, 1000);
		bombsTimer.schedule(new bombsMove(), 0, 50);
		missilesTimer2.schedule(new numberOfMissiles(), 1000, 2000);
		missilesTimer.schedule(new missilesMove(), 0, 50);
		laserTimer.schedule(new laserMove(), 0, 50);
		collisionTimer.schedule(new collisionDetect(), 0, 1);
		remainingtimeTimer.schedule(new remainingtime(), 0, 10);
		endgameTimer.schedule(new endGame(), 0, 100);

	}

	public class BossMove extends TimerTask {

		@Override
		public void run() {

			if (boss.y > 480)
				boss.setdownward(false);
			if (boss.y < 0)
				boss.setdownward(true);
			if (boss.getdownward() == true)
				boss.y += 15;
			if (boss.getdownward() == false)
				boss.y -= 15;
			repaint();

		}

	}

	public class GokMove extends TimerTask {

		@Override
		public void run() {
			if (!gokList.isEmpty())
				for (int i = 0; i < gokList.size(); i++) {
					gokList.get(i).x -= 10;
				}

			repaint();
		}
	}

	public class numberOfGok extends TimerTask {

		@Override
		public void run() {
			if (gokCounter < 4) {

				gokList.add(createGok());
				gokCounter++;

			}
			if (!gokList.isEmpty()) {

				if (gokList.get(0).x < 0) {
					gokList.remove(0);
					gokCounter--;

				}
			}
		}

	}

	public class bombsMove extends TimerTask {

		@Override
		public void run() {
			if (!bombsList.isEmpty())
				for (int i = 0; i < bombsList.size(); i++) {
					bombsList.get(i).x -= 10;
					bombsList.get(i).y = (int) (Math.sin(Math
							.toRadians(bombsList.get(i).sin)) * 100 + bombsList
							.get(i).starty);
					bombsList.get(i).sin += 10;
				}
		}

	}

	public class numberOfBombs extends TimerTask {

		@Override
		public void run() {
			bombsList.add(createBombs());
			if (!bombsList.isEmpty())
				if (bombsList.get(0).x < -100)
					bombsList.remove(0);
		}

	}

	public class numberOfMissiles extends TimerTask {

		@Override
		public void run() {

			for (int i = 0; i < gokList.size(); i++) {
				int a = (int) (Math.random() * 10);
				if (a < 4) {
					missilesList.add(createMissiles());
					// System.out.println(missilesList.size());
				}
			}
			if (!missilesList.isEmpty()) {
				for (int i = 0; i < missilesList.size(); i++)
					if (missilesList.get(i).x < -100) {
						missilesList.remove(i);
					}
			}
		}
	}

	public class missilesMove extends TimerTask {

		@Override
		public void run() {
			if (!missilesList.isEmpty()) {
				for (int i = 0; i < missilesList.size(); i++) {
					missilesList.get(i).x -= 50;
				}
			}
		}

	}

	public class laserMove extends TimerTask {

		@Override
		public void run() {
			if (!laserList.isEmpty())
				for (int i = 0; i < laserList.size(); i++) {
					laserList.get(i).x += 50;
				}

			if (!laserList.isEmpty()) {
				if (laserList.get(0).x > 1000) {
					laserList.remove(0);
				}

			}

		}
	}

	public class collisionDetect extends TimerTask {

		@Override
		public void run() {
			// Gundam hits Boss
			for (int i = 0; i < laserList.size(); i++) {
				if (laserList.get(i).x > boss.x && laserList.get(i).y > boss.y
						&& laserList.get(i).y < boss.y + 90
						&& laserList.get(i).appear) {
					laserList.get(i).appear = false;
					score += 1;
					// System.out.println(score);
				}
			}
			// Gundam hits Gok
			for (int i = 0; i < laserList.size(); i++) {
				for (int j = 0; j < gokList.size(); j++) {
					if (laserList.get(i).x > gokList.get(j).x - 10
							&& laserList.get(i).x < gokList.get(j).x + 58
							&& laserList.get(i).y > gokList.get(j).y - 10
							&& laserList.get(i).y < gokList.get(j).y + 58
							&& laserList.get(i).appear && gokList.get(j).appear) {
						laserList.get(i).appear = false;
						gokList.get(j).appear = false;
						score += 1;
					}
				}

			}
			// Gok hits Gundam
			for (int i = 0; i < missilesList.size(); i++)
				if (missilesList.get(i).x < gundam.x
						&& missilesList.get(i).x > gundam.x - 32
						&& missilesList.get(i).y > gundam.y
						&& missilesList.get(i).y < gundam.y + 32
						&& missilesList.get(i).appear) {
					missilesList.get(i).appear = false;
					score = 0;
				}
			// Boss hits Gundam
			for (int i = 0; i < bombsList.size(); i++)
				if (bombsList.get(i).x < gundam.x + 10
						&& bombsList.get(i).x > gundam.x - 42
						&& bombsList.get(i).y > gundam.y - 10
						&& bombsList.get(i).y < gundam.y + 42
						&& bombsList.get(i).appear) {
					bombsList.get(i).appear = false;
					score = 0;
				}
		}

	}

	public class remainingtime extends TimerTask {

		@Override
		public void run() {
			Calendar nowTime = Calendar.getInstance();

			remainingtime = (((nowTime.getTimeInMillis()) - (beginTime
					.getTimeInMillis())));
			timeLeft = Round(30 - remainingtime / 1000, 2);
		}

	}

	public class endGame extends TimerTask {

		@Override
		public void run() {
			if (timeLeft < 0) {
				endGame();
				timeLeft = 0;
			}
		}

	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		// Background Image
		g.drawImage(backgroundImage[0], 0, 0, null);
		// Boss Image
		g.drawImage(bossImage[0], boss.x, boss.y, null);
		// Gok Image
		for (int i = 0; i < gokList.size(); i++)
			if (gokList.get(i).appear)
				if (gokList.get(i).redOrBlue == true)
					g.drawImage(gokImage[0], gokList.get(i).x,
							gokList.get(i).y, null);
				else
					g.drawImage(gokImage[1], gokList.get(i).x,
							gokList.get(i).y, null);
		// Bomb Image
		for (int i = 0; i < bombsList.size(); i++)
			if (bombsList.get(i).appear)
				g.drawImage(bombsImage[0], bombsList.get(i).x,
						bombsList.get(i).y, null);
		// Missile Image
		for (int i = 0; i < missilesList.size(); i++) {
			if (missilesList.get(i).appear)
				g.drawImage(missileImage[0], missilesList.get(i).x,
						missilesList.get(i).y, null);

		}
		// Laser Image

		for (int i = 0; i < laserList.size(); i++)
			if (laserList.get(i).appear)
				g.drawImage(laserImage[0], laserList.get(i).x,
						laserList.get(i).y, null);
		// Gundam Image
		g.drawImage(gundamImage[0], gundam.x, gundam.y, null);

		// Game text
		Font font = new Font("Arial", Font.PLAIN, 25);
		g.setFont(font);
		g.setColor(Color.WHITE);
		g.drawString("Gundam War", 50, 60);

		// Speed
		g.drawString("Speed: ", 50, 100);
		Graphics2D g2d = (Graphics2D) g;
		GradientPaint gradient = new GradientPaint(10, 10, Color.green, 80,
				100, Color.red, true);
		g2d.setPaint(gradient);
		g2d.fillRect(50, 120, (int) (30 * gundam.m), 20);

		// Remaining time
		g.setColor(Color.WHITE);
		g.drawString("Remaining Time: ", 600, 60);
		g.drawString(String.valueOf(timeLeft) + "s", 800, 60);

		// Score
		g.setColor(Color.WHITE);
		g.drawString("Score: ", 750, 100);
		g.drawString(String.valueOf(score), 850, 100);

	}

}
